using System;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Middleware
{
    /// <summary>
    /// 国际化中间件
    /// 自动检测和设置请求的语言文化
    /// </summary>
    public class LocalizationMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<LocalizationMiddleware> _logger;
        private readonly LocalizationOptions _options;

        public LocalizationMiddleware(
            RequestDelegate next,
            ILogger<LocalizationMiddleware> logger,
            IOptions<LocalizationOptions> options)
        {
            _next = next;
            _logger = logger;
            _options = options.Value;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            try
            {
                var culture = await DetermineCultureAsync(context);
                
                if (culture != null)
                {
                    CultureInfo.CurrentCulture = culture;
                    CultureInfo.CurrentUICulture = culture;
                    
                    // 设置响应头
                    context.Response.Headers["Content-Language"] = culture.Name;
                    
                    _logger.LogDebug("设置请求文化: {Culture}", culture.Name);
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "设置国际化文化时发生错误，使用默认文化");
            }

            await _next(context);
        }

    private Task<CultureInfo?> DetermineCultureAsync(HttpContext context)
        {
            string? cultureName = null;

            // 1. 从查询参数获取
            if (context.Request.Query.ContainsKey("lang"))
            {
                cultureName = context.Request.Query["lang"].FirstOrDefault();
                _logger.LogDebug("从查询参数获取文化: {Culture}", cultureName);
            }

            // 2. 从请求头获取
            if (string.IsNullOrEmpty(cultureName))
            {
                cultureName = context.Request.Headers["Accept-Language"]
                    .FirstOrDefault()?.Split(',').FirstOrDefault()?.Split('-').FirstOrDefault();
                _logger.LogDebug("从请求头获取文化: {Culture}", cultureName);
            }

            // 3. 从Cookie获取
            if (string.IsNullOrEmpty(cultureName))
            {
                cultureName = context.Request.Cookies["culture"];
                _logger.LogDebug("从Cookie获取文化: {Culture}", cultureName);
            }

            // 4. 从用户设置获取（如果已登录）
            if (string.IsNullOrEmpty(cultureName) && context.User.Identity?.IsAuthenticated == true)
            {
                var userCulture = context.User.Claims.FirstOrDefault(c => c.Type == "culture")?.Value;
                if (!string.IsNullOrEmpty(userCulture))
                {
                    cultureName = userCulture;
                    _logger.LogDebug("从用户设置获取文化: {Culture}", cultureName);
                }
            }

            // 验证文化是否支持
            if (!string.IsNullOrEmpty(cultureName))
            {
                try
                {
                    var culture = CultureInfo.GetCultureInfo(cultureName);
                    
                    // 检查是否在支持的文化列表中
                    if (_options.SupportedCultures.Any(c => c.Name == culture.Name))
                    {
                        // 保存到Cookie
                        context.Response.Cookies.Append("culture", culture.Name, new CookieOptions
                        {
                            MaxAge = TimeSpan.FromDays(365),
                            HttpOnly = false,
                            Secure = context.Request.IsHttps
                        });

            return Task.FromResult<CultureInfo?>(culture);
                    }
                    else
                    {
                        _logger.LogWarning("不支持的文化: {Culture}", cultureName);
                    }
                }
                catch (CultureNotFoundException ex)
                {
                    _logger.LogWarning(ex, "无效的文化名称: {Culture}", cultureName);
                }
            }

            // 返回默认文化
        return Task.FromResult<CultureInfo?>(_options.DefaultCulture);
        }
    }

    /// <summary>
    /// 国际化配置选项
    /// </summary>
    public class LocalizationOptions
    {
        /// <summary>
        /// 默认文化
        /// </summary>
        public CultureInfo DefaultCulture { get; set; } = CultureInfo.GetCultureInfo("zh-CN");

        /// <summary>
        /// 支持的文化列表
        /// </summary>
        public CultureInfo[] SupportedCultures { get; set; } = new[]
        {
            CultureInfo.GetCultureInfo("zh-CN"),
            CultureInfo.GetCultureInfo("en-US"),
            CultureInfo.GetCultureInfo("zh-TW"),
            CultureInfo.GetCultureInfo("ja-JP"),
            CultureInfo.GetCultureInfo("ko-KR")
        };

        /// <summary>
        /// 支持的UI文化列表
        /// </summary>
        public CultureInfo[] SupportedUICultures { get; set; } = new[]
        {
            CultureInfo.GetCultureInfo("zh-CN"),
            CultureInfo.GetCultureInfo("en-US"),
            CultureInfo.GetCultureInfo("zh-TW"),
            CultureInfo.GetCultureInfo("ja-JP"),
            CultureInfo.GetCultureInfo("ko-KR")
        };

        /// <summary>
        /// 是否自动从Accept-Language头检测
        /// </summary>
        public bool AutoDetectFromAcceptLanguage { get; set; } = true;

        /// <summary>
        /// 是否保存到Cookie
        /// </summary>
        public bool SaveToCookie { get; set; } = true;

        /// <summary>
        /// Cookie名称
        /// </summary>
        public string CookieName { get; set; } = "culture";

        /// <summary>
        /// Cookie过期时间（天）
        /// </summary>
        public int CookieMaxAgeDays { get; set; } = 365;
    }
}
